/*
 * rt_playback.cpp
 *
 *  Created on: Sep 22, 2011
 *      Author: kunu
 */

//#include <math.h>
#include "stdio.h"
#include "stdlib.h"
#include "rt_playback.h"
#include "synthesiser.h"
#include "globals.h"
#include "stdio.h"

#include <time.h>
#include "RtAudio.h"
#include <iostream>

clock_t start;

int callback(void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
		double streamTime, RtAudioStreamStatus status, void *userData) {
	data_bundle *d = (data_bundle*) userData;
	float *buf_l = (float*) outputBuffer;
	float *buf_r = buf_l + nBufferFrames;

	pthread_mutex_lock((d->buf_d_slot_mutex[d->NRS]));
	while (d->buf_d_status[d->NRS] == SLOT_EMPTY) {
		std::cout << "callback suspended...\n";
		pthread_cond_wait(d->notEmpty, d->buf_d_slot_mutex[d->NRS]);
	}
	// device to host copy..
//	printf(" << consuming slot [%d] val = >>\n", d->NRS);
//	for(int i=0; i<nBufferFrames; i++) {
//		buf_l[i] = sin((d->sidx+i)*2*M_PI/SAMPLE_RATE * 400);
//	}
//	d->sidx+=nBufferFrames;
//	memcpy(buf_r, buf_l, nBufferFrames*sizeof(float));
	start = clock();
	devToHostCopier(buf_l, buf_r, d->buf_d_slot[d->NRS], nBufferFrames);
	duration1 += (clock() - start) / (double)CLOCKS_PER_SEC;
	count+=nBufferFrames;

	pthread_cond_signal(d->notFull);
	d->buf_d_status[d->NRS] = SLOT_EMPTY;
	pthread_mutex_unlock((d->buf_d_slot_mutex[d->NRS]));
	d->NRS++;
	d->NRS %= NUM_SLOTS;

	return 0;
}


rtPlayer::rtPlayer(unsigned int numBufferFrames, unsigned int sampleRate) {
	num_frames = numBufferFrames;
	sample_rate = sampleRate;
}

int rtPlayer::initialize_player(RtAudioCallback callBackFunc, void * data) {
	parameters.deviceId = dac.getDefaultOutputDevice();
	parameters.nChannels = 2;
	parameters.firstChannel = 0;

	options.flags = RTAUDIO_NONINTERLEAVED;
	unsigned int sampleRate = sample_rate;
	unsigned int bufferFrames = num_frames;

//	memset(rtPlayer::buf, 0, (rtPlayer::num_frames)*sizeof(float));
	try {
		dac.openStream(&parameters, NULL, RTAUDIO_FLOAT32, sample_rate,
				&bufferFrames, callBackFunc, data, &options);
	} catch (RtError& e) {
		printf("error \"openStream\"");
		e.printMessage();
		cleanup();
		exit(0);
	}
	return 0;
}

int rtPlayer::play() {
	try {
		dac.startStream();
	} catch (RtError& e) {
		printf("error \"startStream\"");
		e.printMessage();
		cleanup();
	}
	return 0;
}

int rtPlayer::pause() {
	return 0;
}

int rtPlayer::stop() {
	try {
		if (dac.isStreamRunning()) {
			printf("stream running... stopping stream...\n");
			dac.stopStream();
		}
	} catch (RtError& e) {
		e.printMessage();
		exit(1);
	}
	return 0;
}

void rtPlayer::cleanup() {
	printf("cleanup..\n");
	try {
		if (dac.isStreamOpen()) {
			if (dac.isStreamRunning()) {
				dac.stopStream();
			}
			printf("closing stream...\n");
			dac.closeStream();
		}
	} catch (RtError& e) {
		e.printMessage();
		exit(1);
	}
}
